--- /dev/null
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2012 Benjamin Otte <otte@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gdkhslaprivate.h"
+
+#include <math.h>
+
+void
+_gdk_hsla_init_from_rgba (GdkHSLA *hsla,
+ const GdkRGBA *rgba)
+{
+ float min;
+ float max;
+ float red;
+ float green;
+ float blue;
+ float delta;
+
+ g_return_if_fail (hsla != NULL);
+ g_return_if_fail (rgba != NULL);
+
+ red = rgba->red;
+ green = rgba->green;
+ blue = rgba->blue;
+
+ if (red > green)
+ {
+ if (red > blue)
+ max = red;
+ else
+ max = blue;
+
+ if (green < blue)
+ min = green;
+ else
+ min = blue;
+ }
+ else
+ {
+ if (green > blue)
+ max = green;
+ else
+ max = blue;
+
+ if (red < blue)
+ min = red;
+ else
+ min = blue;
+ }
+
+ hsla->lightness = (max + min) / 2;
+ hsla->saturation = 0;
+ hsla->hue = 0;
+ hsla->alpha = rgba->alpha;
+
+ if (max != min)
+ {
+ if (hsla->lightness <= 0.5)
+ hsla->saturation = (max - min) / (max + min);
+ else
+ hsla->saturation = (max - min) / (2 - max - min);
+
+ delta = max -min;
+ if (red == max)
+ hsla->hue = (green - blue) / delta;
+ else if (green == max)
+ hsla->hue = 2 + (blue - red) / delta;
+ else if (blue == max)
+ hsla->hue = 4 + (red - green) / delta;
+
+ hsla->hue *= 60;
+ if (hsla->hue < 0.0)
+ hsla->hue += 360;
+ }
+}
+
+void
+_gdk_rgba_init_from_hsla (GdkRGBA *rgba,
+ const GdkHSLA *hsla)
+{
+ float hue;
+ float lightness;
+ float saturation;
+ float m1, m2;
+
+ lightness = hsla->lightness;
+ saturation = hsla->saturation;
+
+ if (lightness <= 0.5)
+ m2 = lightness * (1 + saturation);
+ else
+ m2 = lightness + saturation - lightness * saturation;
+ m1 = 2 * lightness - m2;
+
+ rgba->alpha = hsla->alpha;
+
+ if (saturation == 0)
+ {
+ rgba->red = lightness;
+ rgba->green = lightness;
+ rgba->blue = lightness;
+ }
+ else
+ {
+ hue = hsla->hue + 120;
+ while (hue > 360)
+ hue -= 360;
+ while (hue < 0)
+ hue += 360;
+
+ if (hue < 60)
+ rgba->red = m1 + (m2 - m1) * hue / 60;
+ else if (hue < 180)
+ rgba->red = m2;
+ else if (hue < 240)
+ rgba->red = m1 + (m2 - m1) * (240 - hue) / 60;
+ else
+ rgba->red = m1;
+
+ hue = hsla->hue;
+ while (hue > 360)
+ hue -= 360;
+ while (hue < 0)
+ hue += 360;
+
+ if (hue < 60)
+ rgba->green = m1 + (m2 - m1) * hue / 60;
+ else if (hue < 180)
+ rgba->green = m2;
+ else if (hue < 240)
+ rgba->green = m1 + (m2 - m1) * (240 - hue) / 60;
+ else
+ rgba->green = m1;
+
+ hue = hsla->hue - 120;
+ while (hue > 360)
+ hue -= 360;
+ while (hue < 0)
+ hue += 360;
+
+ if (hue < 60)
+ rgba->blue = m1 + (m2 - m1) * hue / 60;
+ else if (hue < 180)
+ rgba->blue = m2;
+ else if (hue < 240)
+ rgba->blue = m1 + (m2 - m1) * (240 - hue) / 60;
+ else
+ rgba->blue = m1;
+ }
+}
+
+void
+_gdk_hsla_shade (GdkHSLA *dest,
+ const GdkHSLA *src,
+ float factor)
+{
+ g_return_if_fail (dest != NULL);
+ g_return_if_fail (src != NULL);
+
+ dest->hue = src->hue;
+
+ dest->lightness = src->lightness * factor;
+ dest->lightness = CLAMP (dest->lightness, 0.0, 1.0);
+
+ dest->saturation = src->saturation * factor;
+ dest->saturation = CLAMP (dest->saturation, 0.0, 1.0);
+
+ dest->alpha = src->alpha;
+}
--- /dev/null
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2012 Benjamin Otte <otte@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GTK_HSLA_PRIVATE_H__
+#define __GTK_HSLA_PRIVATE_H__
+
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GdkHSLA GdkHSLA;
+
+struct _GdkHSLA {
+ float hue;
+ float saturation;
+ float lightness;
+ float alpha;
+};
+
+void _gdk_hsla_init_from_rgba (GdkHSLA *hsla,
+ const GdkRGBA *rgba);
+/* Yes, I can name that function like this! */
+void _gdk_rgba_init_from_hsla (GdkRGBA *rgba,
+ const GdkHSLA *hsla);
+
+void _gdk_hsla_shade (GdkHSLA *dest,
+ const GdkHSLA *src,
+ float factor);
+
+G_END_DECLS
+
+#endif /* __GTK_HSLA_PRIVATE_H__ */
#include <errno.h>
#include <math.h>
+#include "gdkhslaprivate.h"
G_DEFINE_BOXED_TYPE (GdkRGBA, gdk_rgba,
gdk_rgba_copy, gdk_rgba_free)
const char *spec)
{
gboolean has_alpha;
+ gboolean is_hsl;
double r, g, b, a;
char *str = (char *) spec;
char *p;
if (strncmp (str, "rgba", 4) == 0)
{
has_alpha = TRUE;
+ is_hsl = FALSE;
str += 4;
}
else if (strncmp (str, "rgb", 3) == 0)
{
has_alpha = FALSE;
+ is_hsl = FALSE;
+ a = 1;
+ str += 3;
+ }
+ else if (strncmp (str, "hsla", 4) == 0)
+ {
+ has_alpha = TRUE;
+ is_hsl = TRUE;
+ str += 4;
+ }
+ else if (strncmp (str, "hsl", 3) == 0)
+ {
+ has_alpha = FALSE;
+ is_hsl = TRUE;
a = 1;
str += 3;
}
if (rgba)
{
- rgba->red = CLAMP (r, 0, 1);
- rgba->green = CLAMP (g, 0, 1);
- rgba->blue = CLAMP (b, 0, 1);
- rgba->alpha = CLAMP (a, 0, 1);
+ if (is_hsl)
+ {
+ GdkHSLA hsla;
+ hsla.hue = r * 255;
+ hsla.saturation = CLAMP (g, 0, 1);
+ hsla.lightness = CLAMP (b, 0, 1);
+ hsla.alpha = CLAMP (a, 0, 1);
+ _gdk_rgba_init_from_hsla (rgba, &hsla);
+ }
+ else
+ {
+ rgba->red = CLAMP (r, 0, 1);
+ rgba->green = CLAMP (g, 0, 1);
+ rgba->blue = CLAMP (b, 0, 1);
+ rgba->alpha = CLAMP (a, 0, 1);
+ }
}
return TRUE;
}
}
+static guint
+parse_hsla_color_channel (GtkCssParser *parser,
+ guint arg,
+ gpointer data)
+{
+ GdkHSLA *hsla = data;
+ double dvalue;
+
+ switch (arg)
+ {
+ case 0:
+ if (!gtk_css_parser_consume_number (parser, &dvalue))
+ return 0;
+ hsla->hue = dvalue;
+ return 1;
+
+ case 1:
+ if (!gtk_css_parser_consume_percentage (parser, &dvalue))
+ return 0;
+ hsla->saturation = CLAMP (dvalue, 0.0, 100.0) / 100.0;
+ return 1;
+
+ case 2:
+ if (!gtk_css_parser_consume_percentage (parser, &dvalue))
+ return 0;
+ hsla->lightness = CLAMP (dvalue, 0.0, 100.0) / 100.0;
+ return 1;
+
+ case 3:
+ if (!gtk_css_parser_consume_number (parser, &dvalue))
+ return 0;
+
+ hsla->alpha = CLAMP (dvalue, 0.0, 1.0) / 1.0;
+ return 1;
+
+ default:
+ g_assert_not_reached ();
+ return 0;
+ }
+}
+
static gboolean
rgba_init_chars (GdkRGBA *rgba,
const char s[8])
{
return gtk_css_parser_consume_function (parser, 4, 4, parse_color_channel, rgba);
}
+ else if (gtk_css_token_is_function (token, "hsl") || gtk_css_token_is_function (token, "hsla"))
+ {
+ GdkHSLA hsla;
+
+ hsla.alpha = 1.0;
+
+ if (!gtk_css_parser_consume_function (parser, 3, 4, parse_hsla_color_channel, &hsla))
+ return FALSE;
+
+ _gdk_rgba_init_from_hsla (rgba, &hsla);
+ return TRUE;
+ }
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID) ||
gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_UNRESTRICTED))
{
'gdkglcontext.c',
'gdkglobals.c',
'gdkgltexture.c',
+ 'gdkhsla.c',
'gdkkeys.c',
'gdkkeyuni.c',
'gdkmemorytexture.c',
gdk_private_h_sources = files([
'gdkeventsprivate.h',
'gdkdevicetoolprivate.h',
+ 'gdkhslaprivate.h',
'gdkmonitorprivate.h',
'gdkseatdefaultprivate.h',
'gdktoplevelsizeprivate.h',
#include "gtkcsscolorvalueprivate.h"
#include "gtkcssstylepropertyprivate.h"
-#include "gtkhslaprivate.h"
#include "gtkprivate.h"
#include "gtkstylepropertyprivate.h"
+#include "gdk/gdkhslaprivate.h"
#include "gdk/gdkrgbaprivate.h"
typedef enum {
GdkRGBA *out,
double factor)
{
- GtkHSLA hsla;
+ GdkHSLA hsla;
- _gtk_hsla_init_from_rgba (&hsla, in);
- _gtk_hsla_shade (&hsla, &hsla, factor);
+ _gdk_hsla_init_from_rgba (&hsla, in);
+ _gdk_hsla_shade (&hsla, &hsla, factor);
_gdk_rgba_init_from_hsla (out, &hsla);
}
|| gtk_css_parser_has_function (parser, "shade")
|| gtk_css_parser_has_function (parser, "alpha")
|| gtk_css_parser_has_function (parser, "mix")
+ || gtk_css_parser_has_function (parser, "hsl")
+ || gtk_css_parser_has_function (parser, "hsla")
|| gtk_css_parser_has_function (parser, "rgb")
|| gtk_css_parser_has_function (parser, "rgba");
}
+++ /dev/null
-/* GTK - The GIMP Toolkit
- * Copyright (C) 2012 Benjamin Otte <otte@gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "gtkhslaprivate.h"
-
-#include <math.h>
-
-void
-_gtk_hsla_init_from_rgba (GtkHSLA *hsla,
- const GdkRGBA *rgba)
-{
- float min;
- float max;
- float red;
- float green;
- float blue;
- float delta;
-
- g_return_if_fail (hsla != NULL);
- g_return_if_fail (rgba != NULL);
-
- red = rgba->red;
- green = rgba->green;
- blue = rgba->blue;
-
- if (red > green)
- {
- if (red > blue)
- max = red;
- else
- max = blue;
-
- if (green < blue)
- min = green;
- else
- min = blue;
- }
- else
- {
- if (green > blue)
- max = green;
- else
- max = blue;
-
- if (red < blue)
- min = red;
- else
- min = blue;
- }
-
- hsla->lightness = (max + min) / 2;
- hsla->saturation = 0;
- hsla->hue = 0;
- hsla->alpha = rgba->alpha;
-
- if (max != min)
- {
- if (hsla->lightness <= 0.5)
- hsla->saturation = (max - min) / (max + min);
- else
- hsla->saturation = (max - min) / (2 - max - min);
-
- delta = max -min;
- if (red == max)
- hsla->hue = (green - blue) / delta;
- else if (green == max)
- hsla->hue = 2 + (blue - red) / delta;
- else if (blue == max)
- hsla->hue = 4 + (red - green) / delta;
-
- hsla->hue *= 60;
- if (hsla->hue < 0.0)
- hsla->hue += 360;
- }
-}
-
-void
-_gdk_rgba_init_from_hsla (GdkRGBA *rgba,
- const GtkHSLA *hsla)
-{
- float hue;
- float lightness;
- float saturation;
- float m1, m2;
-
- lightness = hsla->lightness;
- saturation = hsla->saturation;
-
- if (lightness <= 0.5)
- m2 = lightness * (1 + saturation);
- else
- m2 = lightness + saturation - lightness * saturation;
- m1 = 2 * lightness - m2;
-
- rgba->alpha = hsla->alpha;
-
- if (saturation == 0)
- {
- rgba->red = lightness;
- rgba->green = lightness;
- rgba->blue = lightness;
- }
- else
- {
- hue = hsla->hue + 120;
- while (hue > 360)
- hue -= 360;
- while (hue < 0)
- hue += 360;
-
- if (hue < 60)
- rgba->red = m1 + (m2 - m1) * hue / 60;
- else if (hue < 180)
- rgba->red = m2;
- else if (hue < 240)
- rgba->red = m1 + (m2 - m1) * (240 - hue) / 60;
- else
- rgba->red = m1;
-
- hue = hsla->hue;
- while (hue > 360)
- hue -= 360;
- while (hue < 0)
- hue += 360;
-
- if (hue < 60)
- rgba->green = m1 + (m2 - m1) * hue / 60;
- else if (hue < 180)
- rgba->green = m2;
- else if (hue < 240)
- rgba->green = m1 + (m2 - m1) * (240 - hue) / 60;
- else
- rgba->green = m1;
-
- hue = hsla->hue - 120;
- while (hue > 360)
- hue -= 360;
- while (hue < 0)
- hue += 360;
-
- if (hue < 60)
- rgba->blue = m1 + (m2 - m1) * hue / 60;
- else if (hue < 180)
- rgba->blue = m2;
- else if (hue < 240)
- rgba->blue = m1 + (m2 - m1) * (240 - hue) / 60;
- else
- rgba->blue = m1;
- }
-}
-
-void
-_gtk_hsla_shade (GtkHSLA *dest,
- const GtkHSLA *src,
- float factor)
-{
- g_return_if_fail (dest != NULL);
- g_return_if_fail (src != NULL);
-
- dest->hue = src->hue;
-
- dest->lightness = src->lightness * factor;
- dest->lightness = CLAMP (dest->lightness, 0.0, 1.0);
-
- dest->saturation = src->saturation * factor;
- dest->saturation = CLAMP (dest->saturation, 0.0, 1.0);
-
- dest->alpha = src->alpha;
-}
+++ /dev/null
-/* GTK - The GIMP Toolkit
- * Copyright (C) 2012 Benjamin Otte <otte@gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __GTK_HSLA_PRIVATE_H__
-#define __GTK_HSLA_PRIVATE_H__
-
-#include <gdk/gdk.h>
-
-G_BEGIN_DECLS
-
-typedef struct _GtkHSLA GtkHSLA;
-
-struct _GtkHSLA {
- float hue;
- float saturation;
- float lightness;
- float alpha;
-};
-
-void _gtk_hsla_init_from_rgba (GtkHSLA *hsla,
- const GdkRGBA *rgba);
-/* Yes, I can name that function like this! */
-void _gdk_rgba_init_from_hsla (GdkRGBA *rgba,
- const GtkHSLA *hsla);
-
-void _gtk_hsla_shade (GtkHSLA *dest,
- const GtkHSLA *src,
- float factor);
-
-G_END_DECLS
-
-#endif /* __GTK_HSLA_PRIVATE_H__ */
#include "gtkcssrepeatvalueprivate.h"
#include "gtkcsscolorvalueprivate.h"
#include "gtkcssstyleprivate.h"
-#include "gtkhslaprivate.h"
#include "gtkroundedboxprivate.h"
#include "gtksnapshotprivate.h"
+#include "gdk/gdkhslaprivate.h"
#include "gsk/gskroundedrectprivate.h"
typedef struct _GtkBorderImage GtkBorderImage;
double factor,
GdkRGBA *color_return)
{
- GtkHSLA hsla;
+ GdkHSLA hsla;
- _gtk_hsla_init_from_rgba (&hsla, color);
- _gtk_hsla_shade (&hsla, &hsla, factor);
+ _gdk_hsla_init_from_rgba (&hsla, color);
+ _gdk_hsla_shade (&hsla, &hsla, factor);
_gdk_rgba_init_from_hsla (color_return, &hsla);
}
'gtkfilechooserutils.c',
'gtkfilesystemmodel.c',
'gtkgizmo.c',
- 'gtkhsla.c',
'gtkiconcache.c',
'gtkiconcachevalidator.c',
'gtkiconhelper.c',
--- /dev/null
+a {
+ color: hsl(0, 0%, 0%);
+}
+
+b {
+ color: hsl(120, 100%, 50%);
+}
+
+c {
+ color: hsl(360, 100%, 50%);
+}
+
+d {
+ color: hsl(-314.159, 50%, 50%);
+}
+
+e {
+ color: hsl(0, 0%, 0%, 0.5);
+}
+
+f {
+ color: hsl(1, 2, 3);
+}
--- /dev/null
+hsl.css:22:17-18: error: GTK_CSS_PARSER_ERROR_SYNTAX
--- /dev/null
+a {
+ color: rgb(0,0,0);
+}
+
+b {
+ color: rgb(0,255,0);
+}
+
+c {
+ color: rgb(255,0,0);
+}
+
+d {
+ color: rgb(191,161,64);
+}
+
+e {
+ color: rgba(0,0,0,0.5);
+}
'freed-string-in-error-messages.css',
'freed-string-in-error-messages.errors',
'freed-string-in-error-messages.ref.css',
+ 'hsl.css',
+ 'hsl.errors',
+ 'hsl.ref.css',
'import-cyclic-1.css',
'import-cyclic-1.errors',
'import-cyclic-1.ref.css',
res = gdk_rgba_parse (&color, "#0080ff88");
g_assert_true (res);
g_assert_true (gdk_rgba_equal (&color, &expected));
+
+ expected.red = 1.0;
+ expected.green = 0.0;
+ expected.blue = 0.0;
+ expected.alpha = 1.0;
+ res = gdk_rgba_parse (&color, "hsl (0, 100%, 50%)");
+ g_assert_true (res);
+ g_assert_true (gdk_rgba_equal (&color, &expected));
+
+ expected.red = 0.0;
+ expected.green = 1.0;
+ expected.blue = 0.0;
+ expected.alpha = 0.1;
+ res = gdk_rgba_parse (&color, "hsla (120, 255, 50%, 0.1)");
+ g_assert_true (res);
+ g_assert_true (gdk_rgba_equal (&color, &expected));
+
+ expected.red = 0.0;
+ expected.green = 0.5;
+ expected.blue = 0.5;
+ expected.alpha = 1.0;
+ res = gdk_rgba_parse (&color, "hsl(180, 100%, 25%)");
+ g_assert_true (res);
+ g_assert_true (gdk_rgba_equal (&color, &expected));
}
static void